<template>
  <section class="content">
    <div style="padding-top:20px"></div>
    <details-head v-model="status"
                  :title="`合单信息`"
                  :custom-list="buttonList"
                  :multiple="true"
                  :loading="loading"
                  close-label="返回"
                  @change="submit"
                  @close="back" />
    <el-form ref="ruleForm"
             class="form"
             label-width="100px"
             :model="form"
             :rules="rules"
             label-position="right"
             size="small">
      <el-row :gutter="24">
        <el-col :span="8">
          <el-form-item label="合同编号"
                        prop="contractNo"
                        :rules="[
              {
                required: true,
                message: `请输入合同编号，只可输入数字、字母和特殊符号(-_()&+/[])`,
                validator: validatePactCode,
                trigger: 'blur'
              }
            ]">
            <el-input v-model="form.contractNo"
                      maxlength="30"
                      placeholder="请输入合同编号"></el-input>
          </el-form-item>
        </el-col>
      </el-row>
      <el-row :gutter="24">
        <el-col :span="12">
          <el-form-item label="备注"
                        prop="desc">
            <el-input v-model="form.desc"
                      type="textarea"
                      :rows="3"
                      maxlength="200"
                      placeholder="请输入备注信息"></el-input>
          </el-form-item>
        </el-col>
      </el-row>
    </el-form>
    <div class="titleSty">子单信息</div>
    <div class="totalSty">
      <div class="amountSty fontSty">
        <div>
          订单货物： 总数量{{ amount.totalQuantity || 0 }}件，总重量{{
            amount.calculateWeight || 0
          }}公斤，总体积{{ amount.calculateVolume || 0 }}立方米
        </div>
        <div class="pl40">
          补差：重量{{ amount.lackWeight || 0 }}公斤，体积{{
            amount.lackVolume || 0
          }}立方米
        </div>
      </div>
      <div class="amountSty">
        <div class="addChildOrder pointer"
             @click="childVisible = true">
          <icon-svg icon-name="tianjia"
                    class-name="iconSty-1" />添加子单
        </div>
      </div>
    </div>
    <order-list :table-data="tableData"
                :current-data="currentData"
                :col-width="202"
                :page="page"
                :page-size="pageSize"
                :table-footer="false"
                :selection-flag="false"
                :operation-flag="true"
                :combine-id="combineId"
                :combine-no="combineNo"
                :is-invalid="isCopy"
                @editWaybill="editWaybill"
                @deleteHandel="deleteHandel"
                @calc="calc" />
    <div class="footer-item">
      <el-pagination :current-page="page"
                     :page-size="pageSize"
                     :total="total"
                     :page-sizes="[10, 20, 50, 100]"
                     layout="total, sizes, prev, pager, next, jumper"
                     style="height: 96px"
                     @size-change="handleSizeChange"
                     @current-change="handleCurrentChange">
      </el-pagination>
    </div>
    <add-child-order-dialog v-if="childVisible"
                            :child-visible.sync="childVisible"
                            :ship-mode="shipMode"
                            :table-data="tableData"
                            @changeTableData="changeTableData" />
    <dispatch-dialog v-if="dispatchVisible"
                     :dispatch-visible.sync="dispatchVisible"
                     :dispatch-type="'combine'"
                     :form="{...form, ...amount, tableData, billDayStatus}"
                     @selectCarrier="selectCarrier" />
  </section>
</template>

<script>
import DetailsHead from "@components/detailsHead/Header.vue";
import OrderList from "./components/OrderList.vue";
import AddChildOrderDialog from "./components/AddChildOrderDialog.vue";
import DispatchDialog from "@/components/public/DispatchDialog.vue";
import { onebill } from "@/api/index";
import completeData from "@/libs/conversion.js";
import { mapState, mapActions } from "vuex";
export default {
  name: "OneBill",
  components: {
    DetailsHead,
    OrderList,
    AddChildOrderDialog,
    DispatchDialog
  },
  data () {
    return {
      loading: false,
      visible: false,
      childVisible: false,
      dispatchVisible: false,
      status: "1",
      shipMode: null,
      buttonList: [
        { label: "保存", status: "1" },
        { label: "调度", status: "2" }
      ],
      tableData: [], //总数据源
      currentData: [], //当前数据
      dataList: [], //有效运单
      page: 1,
      pageSize: 10,
      total: 0,
      amount: {
        totalQuantity: 0,
        calculateWeight: 0, // 调整后的重量
        calculateVolume: 0, // 调整后的体积
        calculateValue: 0, //总价值
        originalWeight: 0, // 原重量
        originalVolume: 0, // 原体积
        lackWeight: 0, // 补差重量
        lackVolume: 0 // 补差体积
      },
      form: {
        contractNo: null,
        desc: null
      },
      rules: {
        contractNo: [
          { required: true, message: "请输入合同编号", trigger: "blur" }
        ]
      },
      combineNo: null, // 被复制的合单原始编号
      billDayStatus: false,   // 合单子单中是否有子单过关账期
    };
  },
  computed: {
    combineId () {
      return this.$route.query?.combineId || null;
    },
    close () {
      return [10, 20, 50, 60];
    },
    isCopy () {
      const { name } = this.$route
      return name === 'copyOneBill'
    },
    ...mapState({
      combineBatchEntry: (state) => state.combine.combineBatchEntry
    })
  },
  mounted () {
    if (this.combineId) {
      if (this.isCopy) {
        this.getCombineCopy();
      } else {
        this.getCombineDetail();
      }
    } else {
      if (this.$route.params?.batchEntry) {
        this.tableData = this.$route.params?.batchEntry || [];
        this.currentData = JSON.parse(JSON.stringify(this.tableData)).splice(
          0,
          this.pageSize
        );
        this.total = this.tableData?.length;
        this.shipMode = this.tableData[0].shipMode;
        this.amountCount();
        this.getCombineNo();
      } else {
        this.editWaybillCombine();
      }
    }
  },
  methods: {
    ...mapActions({
      saveCombineBatchEntry: "combine/saveCombineBatchEntry"
    }),
    editWaybill (row, index) {
      this.saveCombineBatchEntry({
        form: { ...this.form },
        index,
        page: this.page,
        pageSize: this.pageSize,
        tableData: this.tableData,
      })
      this.$router.push({
        name: `scheduleDetail`,
        query: {
          waybillId: row.waybillId || row.id
        },
        params: {
          editCombine: 1
        }
      });
    },
    editWaybillCombine () {
      this.tableData = this.combineBatchEntry?.tableData || [];
      this.form = { ...this.combineBatchEntry?.form };
      this.page = this.combineBatchEntry?.page;
      this.pageSize = this.combineBatchEntry?.pageSize;
      this.currentData = JSON.parse(JSON.stringify(this.tableData)).splice(
        (this.page - 1) * this.pageSize,
        this.page * this.pageSize
      );
      this.total = this.tableData?.length;
      this.shipMode = this.tableData[0].shipMode;
      this.amountCount();
    },
    // 计算amount
    amountCount () {
      if (this.total > 0) {
        this.tableData.map((item) => {
          item.makeupWeight = 0;
          item.makeupVolume = 0;
          this.amount.totalQuantity += item.totalQuantity;
          this.amount.calculateWeight += item.calculateWeight;
          this.amount.calculateVolume += item.calculateVolume;
          this.amount.calculateValue += item.calculateValue;
          this.amount.originalWeight += item.totalWeight;
          this.amount.originalVolume += item.totalVolume;
        });
        this.amount.calculateWeight = Number(this.amount.calculateWeight.toFixed(2))
        this.amount.calculateVolume = Number(this.amount.calculateVolume.toFixed(2))
        this.amount.originalWeight = Number(this.amount.originalWeight.toFixed(2))
        this.amount.originalVolume = Number(this.amount.originalVolume.toFixed(2))
        this.amount.lackWeight = Number((this.amount.calculateWeight - this.amount.originalWeight).toFixed(2))
        this.amount.lackVolume = Number((this.amount.calculateVolume - this.amount.originalVolume).toFixed(2))
      }
    },
    // 数组排序
    listSort (list) {
      let invalid = [];
      let effective = [];
      list.map(item => {
        if ((this.combineNo && item.combineNo && item.combineNo != this.combineNo) || item.status != 10 || this.close.includes(item.closeStatus) || item.billDayStatus) {
          invalid.push(item);
        } else {
          effective.push(item);
        }
      });
      return [...invalid, ...effective];
    },
    // 合单合同号
    async getCombineNo () {
      let { data } = await onebill.getCombineNo();
      if (data) {
        this.form.contractNo = data;
      }
    },
    // 合单复制
    async getCombineCopy () {
      let { data } = await onebill.getCombineCopy(this.combineId);
      if (this.combineBatchEntry?.tableData) {
        this.editWaybillCombine();
      } else {
        let arr = this.listSort(data.waybills);
        this.tableData = completeData.redirect(arr);
        this.total = data.waybills.length;
        this.currentData = JSON.parse(JSON.stringify(this.tableData)).splice(
          0,
          this.pageSize
        );
        this.shipMode = this.currentData[0]?.transportRequirement?.shipMode;
        this.amountCount();
        this.form.contractNo = data.contractNo;
      }
      this.combineNo = data.combineNo;
    },
    // 合单详情
    async getCombineDetail () {
      let { data } = await onebill.getCombineDetail(this.combineId);
      if (this.combineBatchEntry?.tableData) {
        this.editWaybillCombine();
      } else {
        this.tableData = completeData.redirect(data.waybills);
        this.total = data.waybills.length;
        this.currentData = JSON.parse(JSON.stringify(this.tableData)).splice(
          0,
          this.pageSize
        );
        this.shipMode = this.currentData[0]?.transportRequirement?.shipMode;
        this.amount = {
          ...this.amount,
          totalQuantity: data.totalQuantity,
          originalWeight: Number(data.totalWeight.toFixed(2)),
          originalVolume: Number(data.totalVolume.toFixed(2)),
          calculateWeight: Number(data.calculateWeight.toFixed(2)),
          calculateVolume: Number(data.calculateVolume.toFixed(2)),
          calculateValue: Number(data.calculateValue.toFixed(2)),
          lackWeight: Number(data.weightAddition.toFixed(2)),
          lackVolume: Number(data.volumeAddition.toFixed(2)),
        };
        this.form = {
          contractNo: data.contractNo,
          desc: data.desc
        };
      }
    },
    // 合同编号输入校验
    validatePactCode (rule, value, callback) {
      if (value) {
        if (
          value &&
          value.match(/^[a-zA-Z0-9\-\_\(\)\&\+\/\[\]]{0,30}$/) == null
        ) {
          callback(
            new Error("请输入合同编号，只可输入数字、字母和特殊符号(-_()&+/[])")
          );
        } else {
          callback();
        }
      } else {
        callback(new Error("请输入合同编号"));
      }
    },
    // 分页数量改变
    handleSizeChange (value) {
      let arr = JSON.parse(JSON.stringify(this.tableData)).splice(0, value);
      this.currentData = [...arr];
      this.page = 1;
      this.pageSize = value;
    },
    // 当前页数改变
    handleCurrentChange (value) {
      let arr = [];
      let tableLength = this.tableData?.length + '';
      value = value ? value : 1;

      if (tableLength[tableLength.length - 1] == 0 && (value > Number(tableLength[0]))) {
        arr = JSON.parse(JSON.stringify(this.tableData)).splice(
          (value - 2) * this.pageSize,
          (value - 1) * this.pageSize
        );
        this.page = value - 1;
      } else {
        arr = JSON.parse(JSON.stringify(this.tableData)).splice(
          (value - 1) * this.pageSize,
          value * this.pageSize
        );
        this.page = value;
      }
      this.currentData = [...arr];
    },
    //移出
    deleteHandel (index) {
      let arr = JSON.parse(JSON.stringify(this.tableData))
      arr.splice(index, 1);
      this.tableData = arr;
      this.calc(this.tableData);
      this.handleCurrentChange(this.page);
      this.saveCombineBatchEntry({
        form: { ...this.form },
        page: this.page,
        pageSize: this.pageSize,
        tableData: this.tableData,
      })
    },
    // 添加子单
    changeTableData (data) {
      this.tableData = this.listSort([...this.tableData, ...data]);
      this.calc(this.tableData);
      this.handleCurrentChange(this.page);

      this.saveCombineBatchEntry({
        form: { ...this.form },
        page: this.page,
        pageSize: this.pageSize,
        tableData: this.tableData,
      })
    },
    // 计算
    calc () {
      this.total = this.tableData.length;
      this.amount.totalQuantity = 0;
      this.amount.calculateWeight = 0;
      this.amount.calculateVolume = 0;
      this.amount.calculateValue = 0;
      this.amount.originalWeight = 0;
      this.amount.originalVolume = 0;
      this.tableData.map((item) => {
        this.amount.calculateValue += item.calculateValue;
        this.amount.totalQuantity += item.totalQuantity;
        this.amount.originalWeight += item.totalWeight;
        this.amount.originalVolume += item.totalVolume;
        this.amount.calculateWeight +=
          !item.makeupWeight || item.makeupWeight === 0
            ? item.calculateWeight
            : item.makeupWeight;
        this.amount.calculateVolume +=
          !item.makeupVolume || item.makeupVolume === 0
            ? item.calculateVolume
            : item.makeupVolume;
      });
      this.amount.calculateWeight = Number(this.amount.calculateWeight.toFixed(2))
      this.amount.calculateVolume = Number(this.amount.calculateVolume.toFixed(2))
      this.amount.originalWeight = Number(this.amount.originalWeight.toFixed(2))
      this.amount.originalVolume = Number(this.amount.originalVolume.toFixed(2))
      this.amount.lackWeight = Number((this.amount.calculateWeight - this.amount.originalWeight).toFixed(2))
      this.amount.lackVolume = Number((this.amount.calculateVolume - this.amount.originalVolume).toFixed(2))
    },
    // 保存
    async save (params) {
      if (this.combineId && !this.isCopy) {
        params.combineId = Number(this.combineId);
        let { code } = await onebill.combinedUpdate(params)
          .catch(() => {
            this.loading = false;
          })
        if (code === 0) {
          this.loading = false;
          this.$message.success("保存成功！");
          this.$router.back();
          this.back();
        }
      } else {
        let { code } = await onebill.combined(params)
          .catch(() => {
            this.loading = false;
          })
        if (code === 0) {
          this.loading = false;
          this.$message.success("保存成功！");
          this.$router.back();
          this.back();
        }
      }
    },
    // 调度
    async dispatch (params) {
      if (this.combineId && !this.isCopy) {
        params.combineId = Number(this.combineId);
      }
      let { code } = await onebill.dispatch(params)
        .catch(() => {
          this.loading = false;
        })
      if (code === 0) {
        this.loading = false;
        this.$message.success("调度成功！");
        this.$router.back();
        this.back();
      }
    },
    // 触发事件
    submit (val) {
      this.$refs.ruleForm.validate((valid) => {
        if (valid) {
          // 复制的合单保存前置校验
          if (this.isCopy) {
            let unCombineWaybill = [];
            let combineWaybill = [];
            this.tableData.map((item) => {
              if ((item.combineNo && item.combineNo != this.combineNo) || item.status != 10) {
                unCombineWaybill.push(item.contractNo);
              } else {
                combineWaybill.push({ ...item });
              }
            });
            if (unCombineWaybill.length) {
              return this.$confirm(`您的合单中存在不可使用的子单, 需剔除方可进行下一步，子单合同编号为：${unCombineWaybill.toString()}，去除后${val === '1' ? '保存' : '调度'}?`, "合单失败！", {
                confirmButtonText: "我知道了",
                type: "warning",
                closeOnClickModal: false
              }).then(() => {
                if (combineWaybill && combineWaybill.length > 1) {
                  this.beforeSubmit(val, combineWaybill);
                }
              });
            } else {
              this.beforeSubmit(val, this.tableData);
            }
          } else {
            this.beforeSubmit(val, this.tableData);
          }
        }
      });
    },
    beforeSubmit (val, dataList) {
      if (dataList && dataList.length < 2) {
        return this.$confirm(`您的合单子单数至少需要2单才能执行合单操作，请添加。`, "合单失败！", {
          confirmButtonText: "我知道了",
          type: "warning",
          closeOnClickModal: false
        }).then(() => {
          console.log("您的合单子单数至少需要2单才能执行合单操作，请添加。");
        });
      }
      if (dataList && dataList.length > 100) {
        return this.$message.error("最多可选择100单合单");
      }
      if (val === "1") {
        this.loading = true;
        this.save({ ...this.form, childes: this.backChild(dataList) }, 1);
      } else {
        let invalidWaybill = [];
        let dispatchInvalid = [];
        dataList.map(item => {
          if (this.close.includes(item.closeStatus)) {
            invalidWaybill.push(item.contractNo);
          }
          if (item.billDayStatus) {
            dispatchInvalid.push(item.contractNo);
          }
        })
        if (invalidWaybill.length) {
          return this.$message({ type: 'warning', message: `运单(合同号${invalidWaybill.toString()})有关单待办需要处理，暂不能操作` })
        }
        this.dataList = dataList;
        if (dispatchInvalid.length) {
          this.billDayStatus = true;
          return this.$confirm(`运单(合同号${dispatchInvalid.toString()})已过关账期，双方不能再报价，是否确定继续操作?`,
            "提示",
            {
              confirmButtonText: "调度",
              type: "warning",
              closeOnClickModal: false
            }).then(() => {
              this.dispatchVisible = true;
            });
        }
        this.dispatchVisible = true;
      }
    },
    // 选择承运方
    selectCarrier (data) {
      this.loading = true;
      this.dispatch({ ...this.form, childes: this.backChild(this.dataList), ...data });
    },
    backChild (dataList) {
      return dataList.map((item) => {
        return {
          waybillId: item.id,
          // valueAddition: 0,
          // weightAddition: item.makeupWeight ? Number((item.makeupWeight - item.totalWeight).toFixed(2)) : (this.combineId ? item?.waybillCache?.weightAddition : item.weightAddition),
          // volumeAddition: item.makeupVolume ? Number((item.makeupVolume - item.totalVolume).toFixed(2)) : (this.combineId ? item?.waybillCache?.volumeAddition : item.volumeAddition),
        };
      });
    },
    // 返回
    back () {
      this.saveCombineBatchEntry({});
    }
  }
};
</script>
<style lang="scss" scoped>
.no-atTheMoment
  .el-picker-panel__footer
  .el-button
  .el-picker-panel__link-btn
  .el-button--text
  .el-button--mini {
  display: none !important;
}
.content {
  background: var(--prev-bg-white);
  padding: 0 20px;
  height: 100vh;
  overflow-x: hidden;
}
.form {
  padding: 20px;
}
.totalSty {
  display: flex;
  justify-content: space-between;
  align-items: center;
  background-color: #f6f6f6;
  height: 50px;
  padding: 0 30px;
  margin-top: 20px;
  .amountSty {
    display: flex;
  }
  .adjustment {
    padding-left: 25px;
    color: var(--prev-icon-color-orange);
  }
  .addChildOrder {
    color: var(--prev-icon-color-orange);
  }
}
.titleSty {
  height: 16px;
  border-left: 2px solid var(--prev-color-primary);
  padding-left: 6px;
  font-size: 16px;
  font-weight: 500;
  margin-top: 5px;
}
.pl40 {
  padding-left: 40px;
}
.fontSty {
  color: var(--prev-color-text-darkgrey);
}
.iconSty {
  width: 16.13px;
  height: 13.92px;
  color: var(--prev-color-primary);
  margin-right: 5px;
}
.iconSty-1 {
  width: 14.57px;
  height: 14.57px;
  color: var(--prev-color-primary);
  margin-right: 5px;
}
.footer-item {
  display: flex;
  justify-content: center;
  align-items: center;
  margin-top: 12px;
  height: 100px;
}
</style>
